package com.kx.controller;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.kx.vo.Student;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

@Controller
public class MyController {

    /**
     * 处理器方法返回String--表示逻辑视图名称，需要配置视图解析器
     */
    @RequestMapping(value = "/returnStringView.do")
    public String returnStringView(HttpServletRequest request, String name, String age) {
        //可以自动手工添加数据到request作用域
        request.setAttribute("name", name);
        request.setAttribute("age", age);

        System.out.println("name=" + name + " age=" + age);
        //show :逻辑视图名称，项目中配置了视图解析器
        //框架对视图执行forward转发操作
        return "show";
    }

    @RequestMapping(value = "/returnStringView2.do")
    public String returnStringView2(HttpServletRequest request, String name, Integer age) {
        //可以自动手工添加数据到request作用域
        request.setAttribute("name", name);
        request.setAttribute("age", age);

        System.out.println("name=" + name + " age=" + age);
        //show :逻辑视图名称，项目中配置了视图解析器
        //框架对视图执行forward转发操作
        //  /WEB-INF/view/WEB-INF/view/show.jsp.jsp
        return "/WEB-INF/view/show.jsp";        //与视图解析器冲突问题后面再说
    }

    //处理器方法返回void，响应ajax请求
    //手工实现ajax，json数据：代码有重复的1、java对象转为json格式数据。2、通过HttpServletResponse输出json数据
    @RequestMapping(value = "/returnVoidAjax.do")
    public void returnVoidAjax(HttpServletResponse response, String name, Integer age) throws IOException {
        System.out.println("name=" + name + " age=" + age);
        //处理ajax，使用json做数据的格式
        //1、service调用完成了，使用Student表示处理结果
        Student student = new Student();
        student.setName(name);
        student.setAge(age);

        String json = "";
        //2、把结果的对象转为json格式的数据
        if (student != null) {
            ObjectMapper om = new ObjectMapper();
            json = om.writeValueAsString(student);
            System.out.println("student转换的json====" + json);
        }
        //3、输出数据，响应ajax请求
        response.setContentType("application/json;charset=utf-8");
        PrintWriter pw = response.getWriter();
        pw.println(json);
        pw.flush();     //刷新缓存
        pw.close();     //关闭打印流
    }

    /**
     * 处理器方法返回一个Student，通过框架转为json，响应ajax请求
     *
     * @ResponseBody:把处理器方法返回对象转为json后，通过HttpServletResponse输出给浏览器
     */
    @RequestMapping(value = "/returnStudentJson.do")
    @ResponseBody
    public Student doStudentJsonObject(String name, Integer age) {
        //调用service，使用Student表示处理结果
        Student student = new Student();
        student.setName(name);
        student.setAge(age);
        return student;
    }

    /**
     * 处理器方法返回一个list<Student>
     * 返回对象框架的处理流程：
     * 1、框架会把返回List<Student></Student>类型（不推荐map），调用框架中的ArrayList<HttpMessageConverter>中每个类
     * 2、框架会实现类的write()，MappingJackson2HttpMessageConverter的write方法
     * 调用Jackson的ObjectMapper实现转为json array
     */
    @RequestMapping(value = "/returnStudentJsonArray.do")
    @ResponseBody
    public List<Student> doStudentJsonObjectArray(String name, Integer age) {
        List<Student> studentList = new ArrayList<>();
        //调用service，使用Student表示处理结果
        Student student = new Student();
        student.setName("zhangsan");
        student.setAge(12);
        Student student1 = new Student();
        student1.setName("lisi");
        student1.setAge(13);
        studentList.add(student);
        studentList.add(student1);

        return studentList;
    }
    /**
     * 处理器方法返回一个String,String表示数据，不是视图
     * 区分返回值String是视图还是数据，看有木有@ResponseBody
     *
     * 默认使用"text/plain;charset=ISO-8859-1"作为contentType，导致中文有乱码
     * 解决方案：在RequestMapping中加入属性produces，使用这个属性制定新的contentType
     *
     * 返回对象框架的处理流程：
     *       1、框架会把返回String类型，调用框架中的ArrayList<HttpMessageConverter>中每个类的canWrite方法
     *          检查那个HttpMessageConverter接口的实现类能处理String类型的数据
     *       2、框架会实现类的write()，StringHttpMessageConverter的write方法
     *       把字符串按照指定的编码处理
     */
    @RequestMapping(value = "/returnStringData.do",produces = "text/plain;charset=utf-8")
    @ResponseBody
    public String doStringData(String name, Integer age) {
//        Student student = new Student();
//        student.setName("zhangsan");
//        student.setAge(12);

        return "Hello SpringMVC 返回对象，表示数据";
    }
}
